/*  
 *  Nanjing JIYU Technology Co.,Ltd All rights reserved.
 *  Copyright (C) 2022 
 *  ==============================================================
 * 
 *  rgb_led.c 
 *    彩色车尾灯功能实现
 *
 *  --------------------------------------------------------------
 *  
 */

#include "rgb_led.h"

#include "peripheral.h"


extern TIM_HandleTypeDef htim2;
extern DMA_HandleTypeDef hdma_tim2_ch1_trig, hdma_tim2_ch2_trig;

#define PIXEL_NUM 6
#define GRB (3*8)

#define WS_ZERO 30
#define WS_ONE  60


void timer_rgb_led_init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 90 - 1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim2);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

}


uint16_t pixelBuffer[PIXEL_NUM * GRB + 42] = {0};


/* pixel num from 0 start */
void ws281x_left(uint16_t n, uint8_t color[][3])
{
  uint8_t i, row;
  uint16_t memaddr;
  uint16_t buffersize;
  buffersize = (n * 24) + 43;    // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
  memaddr = 0;

  //while(len)
  for (row = 0; row < n; row++)
  {
    for (i = 0; i < 8; i++)  //Green
    {
      pixelBuffer[memaddr] = ((color[row][1] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
    for (i = 0; i < 8; i++) // RED
    {
      pixelBuffer[memaddr] = ((color[row][0] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
    for (i = 0; i < 8; i++) // BLUE
    {
      pixelBuffer[memaddr] = ((color[row][2] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
  }
  HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t *) pixelBuffer, buffersize);
}

/* pixel num from 0 start */
void ws281x_right(uint16_t n, uint8_t color[][3])
{
  uint8_t i, row;
  uint16_t memaddr;
  uint16_t buffersize;
  buffersize = (n * 24) + 43;    // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
  memaddr = 0;

  //while(len)
  for (row = 0; row < n; row++)
  {
    for (i = 0; i < 8; i++)  //Green
    {
      pixelBuffer[memaddr] = ((color[row][1] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
    for (i = 0; i < 8; i++) // RED
    {
      pixelBuffer[memaddr] = ((color[row][0] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
    for (i = 0; i < 8; i++) // BLUE
    {
      pixelBuffer[memaddr] = ((color[row][2] << i) & 0x0080) ? WS_ONE : WS_ZERO;
      memaddr++;
    }
  }
  HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_2, (uint32_t *) pixelBuffer, buffersize);
}



uint8_t rgb[6][3] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
uint8_t rgb1[6][3] = {{0,0,255},{0,0,255},{0,0,255},{0,0,255},{0,0,255},{0,0,255}};
uint8_t rgb2[3][3] = {{255,255,0},{0,255,255},{255,0,255}};

void rgb_led(u8 status)
{
  if (status)
    ws281x_left(6, rgb1);
  else
    ws281x_left(6, rgb);
}




void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *tim_pwmHandle)
{
  if (tim_pwmHandle->Instance == TIM2)
  {
    /* Peripheral clock disable */
    __HAL_RCC_TIM2_CLK_DISABLE();

    /* TIM3 DMA DeInit */
    HAL_DMA_DeInit(tim_pwmHandle->hdma[TIM_DMA_ID_CC1]);
    HAL_DMA_DeInit(tim_pwmHandle->hdma[TIM_DMA_ID_CC2]);
    HAL_DMA_DeInit(tim_pwmHandle->hdma[TIM_DMA_ID_TRIGGER]);

    /* TIM3 interrupt Deinit */
    HAL_NVIC_DisableIRQ(TIM2_IRQn);
  }
}

void DMA1_Channel5_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_tim2_ch1_trig);
}

void DMA1_Channel7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_tim2_ch2_trig);
}

void TIM2_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim2);
}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
  HAL_TIM_PWM_Stop_DMA(htim, TIM_CHANNEL_1);
  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);
  HAL_TIM_PWM_Stop_DMA(htim, TIM_CHANNEL_2);
}






